/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 *
 */

import path from 'path';

import { hvigorCore } from '@ohos/hvigor';
import { HvigorConfigLoader } from '@ohos/hvigor/src/common/util/hvigor-config-loader.js';

import { CommonConst, HvigorConfigConst } from '../const/common-const.js';
import { OhosLogger } from './log/ohos-logger.js';
import { TaskNames } from "../tasks/common/task-names.js";

/**
 * 通过hvigor命令行-p拿到一些固定的值
 *
 * @since 2022/5/17
 */
export class InjectUtil {
  private static _log: OhosLogger = OhosLogger.getLogger('InjectUtil');
  private static startParams = hvigorCore.getParameter().getStartParams();

  // 设置getBuildCacheParentDir()中日志最多打印一次
  static customBuildDirHasLogged = false;

  /**
   * 判断是否是hot reload模式
   * 默认(不配置)是false
   *
   * @returns {boolean}
   */
  static isHotReload(): boolean {
    return hvigorCore.getExtraConfig().get(CommonConst.HOT_RELOAD) === 'true' && this.startParams.daemon;
  }

  static isColdReload(): boolean {
    return hvigorCore.isCommandEntryTask('assembleDevHqf');
  }

  static isDeviceTest(): boolean {
    return hvigorCore.isCommandEntryTask(CommonConst.ON_DEVICE_TEST);
  }

  static isAssembleDevHqf(): boolean {
    return hvigorCore.isCommandEntryTask('assembleDevHqf');
  }

  /**
   * 是否是 daemon 模式
   *
   * @returns {boolean}
   */
  static isDaemon(): boolean {
    return this.startParams.daemon;
  }

  /**
   * 判断是否在preview的流程中调用task
   *
   * @returns {boolean}
   */
  static isPreviewProcess(): boolean {
    return hvigorCore.getExtraConfig().get(CommonConst.PREVIEW_MODE) === 'true';
  }

  /**
   * 判断是否在unitTest的流程中调用task
   *
   * @returns {boolean}
   */
  static isUnitTestProcess(): boolean {
    return hvigorCore.getExtraConfig().get(CommonConst.UNIT_TEST_MODE) === 'true';
  }

  /**
   * 判断是否ohosTest coverage模式打包
   *
   * @returns {boolean}
   */
  static isOhosTestCoverage(): boolean {
    return hvigorCore.getExtraConfig().get(CommonConst.OHOS_TEST_COVERAGE) === 'true';
  }

  static getCoveragePathFilter(): string | undefined {
    return hvigorCore.getExtraConfig().get(CommonConst.COVERAGE_PATH_FILTER);
  }

  static getCoverageMode(): string | undefined {
    return hvigorCore.getExtraConfig().get(CommonConst.COVERAGE_MODE);
  }

  /**
   * 判断是否是启用debugLine
   * 默认(不配置)是false
   *
   * @returns {boolean}
   */
  static isDebugLineEnable(): boolean {
    return hvigorCore.getExtraConfig().get(CommonConst.DEBUG_LINE) === 'true';
  }

  /**
   * 获取build cache的父目录
   *
   * @param baseCacheDir 默认的build cache的父目录
   * @param postfix 用于和自定义build cache拼接的路径后缀
   * @param supportBuildCacheDir 是否支持通过build-cache-dir自定义缓存路径
   * @returns {string}
   */
  static getBuildCacheParentDir(baseCacheDir: string, postfix: string, supportBuildCacheDir = true): string {
    const prefix = InjectUtil.getBuildDir(supportBuildCacheDir);
    if (!prefix) {
      return baseCacheDir;
    }
    if (!path.isAbsolute(prefix)) {
      if (this._log && !this.customBuildDirHasLogged) {
        this._log.warn(`Invalid build cache dir: ${prefix}`);
        this.customBuildDirHasLogged = true;
      }
      return baseCacheDir;
    }
    if (this._log && !this.customBuildDirHasLogged) {
      this._log.warn('Please ensure no projects of the same name have the same build cache dir.');
      this.customBuildDirHasLogged = true;
    }
    return path.join(prefix, postfix.replace(':', path.sep));
  }

  /**
   * 获取模块的buildRootPath
   *
   * @param {string} modulePath 模块路径
   * @return {string} buildRootPath
   */
  static getModuleBuildRootPath(modulePath: string): string {
    return InjectUtil.getBuildCacheParentDir(
      modulePath,

      // Safety: hvigor.getProject()必然已经被初始化
      path.join(hvigorCore.getProject()!.getName(), modulePath.substring(hvigorCore.getProject()!.getNodeDir().length)),
    );
  }

  /**
   * 获取用户自定义build的目录
   *
   * @returns {string | undefined}
   */
  static getBuildDir(supportBuildCacheDir = true): string | undefined {
    let buildCacheDir = hvigorCore.getExtraConfig().get(CommonConst.BUILD_CACHE_DIR);
    if (buildCacheDir && !supportBuildCacheDir) {
      return undefined;
    }
    if (!buildCacheDir) {
      buildCacheDir = HvigorConfigLoader.getInstance().getPropertiesConfigValue<string>(CommonConst.BUILD_DIR_KEY);
      if (!buildCacheDir) {
        return undefined;
      }
    }
    if (this.isPreviewProcess() || this.isInTest()) {
      return undefined;
    }
    return buildCacheDir.replace(/^'|'$/g, '').replace(/^"|"$/g, '');
  }

  /**
   * 判断是否执行的是localTest
   *
   * @returns {boolean}
   */
  static isLocalTest(): boolean {
    return hvigorCore.getExtraConfig().get(CommonConst.IS_LOCAL_TEST) === 'true';
  }

  /**
   * 判断是否执行的是ohosTest
   *
   * @returns {boolean}
   */
  static isOhosTest(): boolean {
    return hvigorCore.getExtraConfig().get(CommonConst.IS_OHOS_TEST) === 'true';
  }

  /**
   * 判断是否执行localTest或ohosTest
   */
  static isInTest(): boolean {
    return this.isLocalTest() || this.isOhosTest();
  }

  static isByteCodeHarOptimize(): boolean {
    return hvigorCore.getParameter().getProperty(HvigorConfigConst.OHOS_BYTE_CODE_HAR_OPTIMIZE) === true;
  }

  /**
   * 判断是否测试框架
   */
  static isTestFrameWork(): boolean {
    return hvigorCore.isCommandEntryTask(TaskNames.CommonHookTask.GEN_ON_DEVICE_TEST_HAP.name)
      || hvigorCore.isCommandEntryTask(TaskNames.Task.UNIT_TEST_BUILD.name)
      || hvigorCore.isCommandEntryTask(TaskNames.Task.TEST.name)
      || hvigorCore.isCommandEntryTask(TaskNames.Task.ON_DEVICE_TEST.name)
      || this.isOhosTestCoverage()
      || this.isInTest();
  }

  /**
   * 获取命令行里的入口模块
   *
   * @returns {string[]}
   */
  static getEntryModulesName(): string[] {
    const moduleStr = hvigorCore.getExtraConfig().get('module');
    if (moduleStr) {
      return moduleStr.split(',').map((x) => x.split('@')[0]);
    }
    return [];
  }
}
